require "win._"
---@class Form
local form = class()

function form:ctor()
    self.wndProcTab = {}
    self.hwnd = 0
    local wc = ffi.new("WNDCLASSA[1]")
    local wndclass = wc[0]
    local hInstance = win.GetModuleHandleA(0)
    wndclass.style = bit.bor(_CS_HREDRAW, _CS_VREDRAW)
    local wndProcTab = self.wndProcTab
    wndclass.lpfnWndProc = function(hwnd, message, wParam, lParam)
        local wndfunc = wndProcTab[message]
        if wndfunc then
            local rs
            for ____, iterator in ipairs(wndfunc) do
                local f = iterator
                local r = f and f(hwnd, message, wParam, lParam)
                rs = rs or r
            end
            if rs ~= nil then
                return rs
            end
        end
        return win.defWindowProc(hwnd, message, wParam, lParam)
    end

    self.wndProc = {
        [_WM_DESTROY] = function()
            win.postQuitMessage(0)
            return 0
        end,
        [_WM_SIZE] = function()
            win.moveWindow(self.hwnd, 0, 0, 800, 800, false)
        end
    }

    local className = "test11111"
    wndclass.hInstance = hInstance
    wndclass.lpszClassName = className
    win.registerClassA(wc)
    self.hwnd =
        win.createWindowExA(
        0,
        className,
        className,
        bit.bor(_WS_OVERLAPPEDWINDOW, _WS_VISIBLE),
        0,
        0,
        800,
        800,
        0,
        ffi.cast("HMENU", 0),
        hInstance,
        ffi.cast("LPVOID", 0)
    )
    win.updateWindow(self.hwnd)
end

form.wndProc = {
    _set = function(self, v)
        if type(v) == "table" then
            for msg, func in pairs(v) do
                if self.wndProcTab[msg] then
                    table.insert(self.wndProcTab[msg], v)
                else
                    self.wndProcTab[msg] = {func}
                end
            end
        end
    end
}

function form:show(sw)
    if sw == nil then
        sw = _SW_SHOWNORMAL
    end
    win.show(self.hwnd, sw)
end

win.form = form
